#ifndef AUTOMATON_COORDINATOR_HPP 
#define AUTOMATON_COORDINATOR_HPP 

#include "Slaves/general/generalPrototype.hpp"
#include <vector>
#include <string>
#include <set>

// use the callback
// also with encoder, to split off later
struct TAutomatonFrameCoordinator :GeneralSlave {
public:
	TAutomatonFrameCoordinator(GeneralSlave* ref);
	~TAutomatonFrameCoordinator();

	struct Subordinates {
		std::vector<GeneralSlave*> subordinateRefs;
		int selectedSubIndex = -100;
		const static int SubIndexSelf = 255;
		std::set<int> debug_allSubIndexes;
		//std::wstring 

		std::wstring nameInRoutingCB;
	}_subs;

	bool isCoordinator() { return true; }

	bool needConfigReroute(int callerIdx, int tempConfigSelf);
	bool updateBridgedNameInLog(std::wstring baseCallerName, int callerIdx, int callerIsAE);
	// baseCallerName: the base slave calling preSendingConfig to configure the link
	// callerIdx: index of direct slave calling this
	// tempConfigSelf: >=0 if configuring this slave without modifying the route (using special commands)
	// callerIsAE: caller is a avatar or embodiment of this, will set nameInLog by the caller. (merge callerIsAE=1 to configSelf=1?)
	// return 0 if configed but not connected (can use 0x11 command to check stat); return -1 if pre sending config not working
	int preSendingConfig(std::wstring baseCallerName, int callerIdx, int tempConfigSelf = -1, int callerIsAE = 0);

	int detectSubordinate(int index, std::wstring& whoOut, std::wstring& whichOut);
	int select(int index);
	int getHopNum();

	int connectThroughTBridge(int discoverMode);
	int connectThroughTBridgeNonRoot(int discoverMode);

	//void virtual updateAfterConnectAny(HandShakeProtocol* protocol);

	int confirmConnected();
	int reConnect();
	int forceRebuildBridges();

private:
	static HandShakeProtocol makeBridgeRootSerialHandshake(std::wstring model, std::wstring id, int hopNum, int discoveryMode);
	int confirmConnectCore(int logWarningOnFailure);
	int formatNameInLogAndCallerIdx(std::wstring baseCallerName, int callerIdx, int callerIsAE);

	struct RoutingCallNameSwitcher {
		std::wstring nameInCB_backup;
		std::wstring *nameInCBRef, * nameInRoutingRef;
		RoutingCallNameSwitcher(std::wstring* nameInCBRefIn, std::wstring* nameInRoutingRef);
		void routineComplete();
		~RoutingCallNameSwitcher();
	};

};


#endif